package com.ss.spider.system.role.service.impl;

import com.ss.exception.ServiceException;
import com.ss.service.AbstractCWServiceImpl;
import com.ss.spider.system.role.mapper.RoleResourceMapper;
import com.ss.spider.system.role.model.RoleResource;
import com.ss.spider.system.role.service.RoleResourceService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


@Service("roleResourceService")
public class RoleResourceServiceImpl
        extends AbstractCWServiceImpl<RoleResource>
        implements RoleResourceService<RoleResource> {

    @Autowired
    private RoleResourceMapper roleResourceMapper;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public List<RoleResource> list(RoleResource entity) {
        return this.roleResourceMapper.list(entity);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public int save(RoleResource entity) throws ServiceException {
        try {
            return this.roleResourceMapper.save(entity);
        } catch (Exception e) {
            this.logger.error("保存角色资源失败,原因:", e);
            throw new ServiceException("保存角色资源失败", e);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public int batchSave(List<RoleResource> list, List<String> resourceIds) throws ServiceException {
        Map<String, List<RoleResource>> map = new HashMap<String, List<RoleResource>>(list.size());

        for (RoleResource resource : list) {
            List<RoleResource> res = (List) map.get(resource.getRoleId());
            if (CollectionUtils.isEmpty(res)) {
                res = new ArrayList<RoleResource>();
                map.put(resource.getRoleId(), res);
            }
            res.add(resource);
        }

        Set<String> keyset = map.keySet();

        int count = 0;

        for (String roleId : keyset) {
            RoleResource entity = new RoleResource();
            entity.setRoleId(roleId);
            List<RoleResource> resources = (List) map.get(roleId);
            List rList = resources.stream().map(RoleResource::getResourceId)
                    .collect(Collectors.toList());
            entity.setResourceIds(rList);
            List<RoleResource> exists = this.roleResourceMapper.list(entity);
            if (CollectionUtils.isNotEmpty(exists)) {
                for (RoleResource resource : exists) {
                    resources.remove(resource);
                }
            }
            if (CollectionUtils.isEmpty(resources)) {
                continue;
            }
            try {
                count += this.roleResourceMapper.batchSave(resources);
            } catch (Exception e) {
                this.logger.error("批量保存角色资源失败,原因:", e);
                throw new ServiceException("批量保存角色资源失败", e);
            }
        }
        return count;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public int delete(RoleResource entity) throws ServiceException {
        try {
            return this.roleResourceMapper.delete(entity);
        } catch (Exception e) {
            this.logger.error("删除角色关联资源失败,原因:", e);
            throw new ServiceException("删除角色关联资源失败", e);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public int delete(List<RoleResource> list) throws ServiceException {
        try {
            for (RoleResource item : list) {
                this.roleResourceMapper.delete(item);
            }
        } catch (Exception e) {
            this.logger.error("删除角色关联资源失败,原因:", e);
            throw new ServiceException("删除角色关联资源失败", e);
        }

        return list.size();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public int delete(final String roleId) throws ServiceException {
        return delete(new RoleResource() {

        });
    }

}
